﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Threading;
using HMS.Data;
using HMS.ClassLibrary;
using HMS.Resources;



namespace HMS
{
    /// <summary>
    /// Interaction logic for ChannlingWindow.xaml
    /// </summary>
    public partial class ChannlingWindow : Window
    {
        private HMSEntities HMSContext;
        private ProgressWindow ProgressWindow;
        FormAction FormAction;
    
        //triggesr updateControlState() when form action changes
        public FormAction CurrentFormAction
        {
            set
            {
                FormAction = value;
                UpdateContolState();
            }
            get { return FormAction; }

        }

        public ChannlingWindow()
        {
            InitializeComponent();
            HMSContext = new HMSEntities();
            InitializeControlState();
            CurrentFormAction = FormAction.View;          
           
        }

        private void InitializeControlState()
        {
            
           

            //set the autocomplete text box data source
            DoctorTypeAutocompleteTextBox.ItemsSource = HMSContext.DoctorTypes;

            //set channeling hours
            ChannelingHourComboBox.DataContext = HMSContext.ChannelingHours;

            //set payment methods
            PaymentMethodComboBox.DataContext = HMSContext.PaymentMethods;

            //set Appoinment Calendar date to today
            AppointmentDatePicker.SelectedDate = DateTime.Now;

            //set payment method to default 'cash'
            PaymentMethodComboBox.SelectedValue = 1;

            //set channeling list
            ReferenceAutocompleteTextBox.ItemsSource = HMSContext.Channelings.Where(c=> c.StatusID==1);

            PatientAgeIntegerUpDown.Value = 0;
        }

        private void ResetControlValues()
        {
            //reset channeling details
            ReferenceAutocompleteTextBox.SelectedItem = null;
            ReferenceAutocompleteTextBox.Text = "";
            DoctorTypeAutocompleteTextBox.SelectedItem = null;
            DoctorAutocompleteTextBox.Text = "";
            DoctorAutocompleteTextBox.SelectedItem = null;
            DoctorAutocompleteTextBox.Text = "";
            AppointmentDatePicker.SelectedDate = DateTime.Now;
            ChannelingHourComboBox.SelectedIndex = -1;

             //reset patient details
            PatientNameTextBox.Text = "";
            PatientAgeIntegerUpDown.Value = 0;
            PatientContactNoTextBox.Text = "";

             //reset payment details
            IsPhoneBookingCheckBox.IsChecked = false;

             //reset summary 
            PatientNumberTextBlock.Text = "0";
            AppoinmentTimeTextBlock.Text = "00:00:00 AM";
            DoctorFeeTextBlock.Text = "0.00";
            HospitalFeeTextBlock.Text = "0.00";
        }

        private decimal CalculateTotalReceiptAmount(Doctor doctor, decimal discountPercentage)
        {
            return (decimal)(doctor.DoctorFee + doctor.HospitalFee);
        }
  

        private bool ValidateControlValues()
        {

            
            if (DoctorTypeAutocompleteTextBox.SelectedItem == null)
            {
                MessageBox.Show(Properties.Resources.DoctorTypeNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }
            if (DoctorAutocompleteTextBox.SelectedItem == null)
            {
                MessageBox.Show(Properties.Resources.DoctorNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }
            if (AppointmentDatePicker.SelectedDate == null)
            {
                MessageBox.Show(Properties.Resources.AppoinmentDateNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;

            }
            if (ChannelingHourComboBox.SelectedIndex == -1)
            {
                MessageBox.Show(Properties.Resources.ChannelingHourNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;

            }
            if (String.IsNullOrEmpty(PatientNameTextBox.Text.Trim()))
            {
                MessageBox.Show(Properties.Resources.PatientNameNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }
            if (PatientAgeIntegerUpDown.Value.Value <= 0 || PatientAgeIntegerUpDown.Value.Value >=120)
            {
                MessageBox.Show(HMS.Resources.Properties.Resources.PatientAgeInvalid, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }
            if (PatientContactNoTextBox.Text.Contains("_"))
            {
                MessageBox.Show(Properties.Resources.ContactNumberInvalid, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);
                return false;
            }

            return true;
        }
        private int GetPatientNumber()
        {
            if (DoctorAutocompleteTextBox.SelectedItem == null)
            {
                return -1;
            }
            if (AppointmentDatePicker.SelectedDate == null)
            {
                return -1;
            }
            if (ChannelingHourComboBox.SelectedIndex == -1)
            {
                return -1;
            }
            try
            {
                Doctor selectedDoctor = DoctorAutocompleteTextBox.SelectedItem as Doctor;
                DateTime? selecteddate = AppointmentDatePicker.SelectedDate;
                ChannelingHour selectedChannelingHour = ChannelingHourComboBox.SelectedItem as ChannelingHour;

                return (int)HMSContext.NextPatientNumber(selectedDoctor.DoctorID, selecteddate, selectedChannelingHour.ChannelingHourID).First();
    
            }
            catch (Exception ex)
            {

                throw ex;
            }
               
        }
       

        private TimeSpan? GetAppoinmentTime()
        {
            if (DoctorAutocompleteTextBox.SelectedItem == null)
            {
                  return null;
            }
            if (AppointmentDatePicker.SelectedDate == null)
            {
                return null;
            }
            if (ChannelingHourComboBox.SelectedIndex == -1)
            {
                 return null;
            }
            try
            {
                Doctor selectedDoctor = DoctorAutocompleteTextBox.SelectedItem as Doctor;
                DateTime? selecteddate = AppointmentDatePicker.SelectedDate;
                ChannelingHour selectedChannelingHour = ChannelingHourComboBox.SelectedItem as ChannelingHour;

                return HMSContext.NextAppoinmentTime(selectedDoctor.DoctorID, selecteddate, selectedChannelingHour.ChannelingHourID).First();

            }
            catch (Exception ex)
            {

                throw ex;
            }

        }
        private void DisplayDetails(Channeling channeling)
        {
            try
            {
                //display channeling details
                ReferenceAutocompleteTextBox.SelectedItem = channeling;
                DoctorTypeAutocompleteTextBox.SelectedItem = channeling.Doctor.DoctorType;
                DoctorAutocompleteTextBox.SelectedItem = channeling.Doctor;
                AppointmentDatePicker.SelectedDate = channeling.AppointmentDateTime;
                ChannelingHourComboBox.SelectedItem = channeling.ChannelingHour;

                //display patient details
                PatientNameTextBox.Text = channeling.Patient.Name;
                PatientAgeIntegerUpDown.Value = channeling.Patient.Age;
                PatientContactNoTextBox.Text = channeling.Patient.ContactNumber;

                //display payment details
                if (channeling.Receipt.PaymentMethodID == 2)
                {
                    IsPhoneBookingCheckBox.IsChecked = true;
                }
                else
                {
                    PaymentMethodComboBox.SelectedItem = channeling.Receipt.PaymentMethod;
                }

                //display summary details
                PatientNumberTextBlock.Text = channeling.PatientNumber.ToString();
                AppoinmentTimeTextBlock.Text = channeling.AppointmentDateTime.Value.ToShortTimeString();
                HospitalFeeTextBlock.Text = channeling.Receipt.HospitalFee.ToString();
                DoctorFeeTextBlock.Text = channeling.Receipt.DoctorFee.ToString();
                TotalReceiptAmountTextBlock.Text = channeling.Receipt.TotalAmount.ToString();
            }
            catch (Exception)
            {
                
                throw;
            }

        }
         
        private void UpdateContolState( )
        {
            switch (this.CurrentFormAction)
            {
                case FormAction.View:
                    ReferenceAutocompleteTextBox.ItemsSource = HMSContext.Channelings.Where(c=> c.StatusID==1);
                    ReferenceAutocompleteTextBox.IsEnabled = true;

                    DoctorTypeAutocompleteTextBox.ItemsSource = null;
                    DoctorTypeAutocompleteTextBox.Text = "";
                    DoctorAutocompleteTextBox.ItemsSource = null;
                    DoctorAutocompleteTextBox.Text = "";                  

                    //set button states
                    SaveButton.IsEnabled = false;
                    //RefreshSummaryButton.IsEnabled = false;
                    NewButton.IsEnabled = true;
                    PrintButton.IsEnabled = true;
                    CancelButton.IsEnabled = true; 
                    CloseButton.IsEnabled = true;
                    break;


                case FormAction.New:
                    ResetControlValues();
                    InitializeControlState();

                    ReferenceAutocompleteTextBox.ItemsSource = null;
                    ReferenceAutocompleteTextBox.IsEnabled = false;

                     //set button states
                    SaveButton.IsEnabled = true;
                    //RefreshSummaryButton.IsEnabled = true;
                    NewButton.IsEnabled = false;
                    PrintButton.IsEnabled = false;
                    CancelButton.IsEnabled = false; 
                    CloseButton.IsEnabled = true;
                    break;
            }

        }
        private void Save()
        {
            try
            {
                 if(ValidateControlValues()) 
                 {
                  
                    //channeling details
                    Doctor doctor = DoctorAutocompleteTextBox.SelectedItem as Doctor;
                    TimeSpan? appointmentTime = this.GetAppoinmentTime();
                    DateTime? appoinmentDate = AppointmentDatePicker.SelectedDate;
                    DateTime appoinmentDateTime = new DateTime(appoinmentDate.Value.Year, appoinmentDate.Value.Month, appoinmentDate.Value.Day
                                                                , appointmentTime.Value.Hours, appointmentTime.Value.Minutes, appointmentTime.Value.Seconds);
                    ChannelingHour channelingHour = ChannelingHourComboBox.SelectedItem as ChannelingHour;
                    String reference = HMSContext.NextSystemNumber(1).First();
                    int patientAge = PatientAgeIntegerUpDown.Value.Value;

                    //patient details
                    string patientName = PatientNameTextBox.Text;
                    string patientContactNo = PatientContactNoTextBox.Text;

                    //payment details
                    PaymentMethod paymentMethod = PaymentMethodComboBox.SelectedItem as PaymentMethod;
                    decimal? totalAmount = this.CalculateTotalReceiptAmount(doctor, 0);
                    DateTime receiptDateTime = DateTime.Now;

                    //summary details
                    int patientNo = this.GetPatientNumber();


                    Patient patient = new Patient();
                    patient.Name = patientName;
                    patient.Age = patientAge;
                    patient.ContactNumber = patientContactNo;

                    Receipt receipt = new Receipt();
                    receipt.ServiceTypeID = 4;
                    receipt.PaymentMethodID = paymentMethod.PaymentMethodID;
                    receipt.ReceiptDateTime = receiptDateTime;
                    receipt.DoctorFee = doctor.DoctorFee;
                    receipt.HospitalFee = doctor.HospitalFee;
                    receipt.UrgentFee = 0;
                    receipt.DiscountAmount = 0;
                    receipt.TotalAmount = totalAmount;
                    receipt.Reference = reference;

                    Channeling channeling = new Channeling();
                    channeling.Doctor = doctor;
                    channeling.PatientNumber = patientNo;
                    channeling.AppointmentDateTime = appoinmentDateTime;
                    channeling.ChannelingHour = channelingHour;
                    channeling.Patient = patient;
                    channeling.Receipt = receipt;
                    channeling.Reference = reference;
                    channeling.UserID = HMSApplication.Session.User.UserID;
                    channeling.StatusID = 1;

                    HMSContext.AddToChannelings(channeling);
                    int? affectedRowCount = HMSContext.SaveChanges();
                    if (affectedRowCount != null && affectedRowCount > 0)
                    {
                        ResetControlValues();
                        if (PrintReceiptCheckBox.IsChecked == true)
                        {
                            this.Print(channeling);
                        }

                        //set the form action to view mode and display the saved channeling details
                        this.CurrentFormAction = FormAction.View;
                        this.DisplayDetails(channeling);
                        MessageBox.Show(Properties.Resources.SaveSuccessful, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);                    
                       
                    }
                    else
                    {
                        MessageBox.Show(Properties.Resources.UnknownError, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                 }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);

            }
        }
        private void Cancel()
        {
            try
            {
              
                Channeling channeling = ReferenceAutocompleteTextBox.SelectedItem as Channeling;
                channeling.StatusID = 2;
                int? affectedRowCount = HMSContext.SaveChanges();
                if (affectedRowCount != null && affectedRowCount > 0)
                {
                    ResetControlValues();
                    InitializeControlState();
                    MessageBox.Show(Properties.Resources.SaveSuccessful, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Information);                    
                       
                }
                else
                {
                    MessageBox.Show(Properties.Resources.UnknownError, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            catch (Exception)
            {
                
                throw;
            }
        }
        private void Print(Channeling channeling)
        {
            try
            {
                 Printer printer = new Printer();
                 printer.Print(channeling.Receipt, ReceiptReportType.ChannelingReceiptHospitalReport);
                 printer.Print(channeling.Receipt,ReceiptReportType.ChannelingReceiptDoctorReport);
            }
            catch (Exception)
            {
                
                throw;
            }

        }
        private void UpdateSummary()
        {
            try
            {
                if (ChannelingHourComboBox.SelectedIndex == -1)
                {
                    return;
                }

                if (DoctorAutocompleteTextBox.SelectedItem == null)
                {
                     return;
                }
                if (AppointmentDatePicker.SelectedDate == null)
                {
                     return;
                }

                UpdateChannelingSummary();

            }
            catch (Exception )
            {

                throw;

            }

        }


        private void UpdateChannelingSummary()
        {
            try
            {
                //update patient no
                int patientNumber = this.GetPatientNumber();
                if (patientNumber != -1)
                {
                    PatientNumberTextBlock.Text = patientNumber.ToString();
                }

                //update appoinment time
                TimeSpan? appoinmentTime = GetAppoinmentTime();
                if (appoinmentTime != null)
                {
                    DateTime appoinmentDate = AppointmentDatePicker.SelectedDate.Value;
                    AppoinmentTimeTextBlock.Text = new DateTime(appoinmentDate.Year, appoinmentDate.Month, appoinmentDate.Day, appoinmentTime.Value.Hours, appoinmentTime.Value.Minutes, appoinmentTime.Value.Seconds).ToShortTimeString();
                }
            }
            catch (Exception ex)
            {               
                throw ex;
            }
        }


        private void DoctorTypeAutocompleteTextBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (DoctorTypeAutocompleteTextBox.SelectedItem != null)
                {
                    DoctorType selectedType = DoctorTypeAutocompleteTextBox.SelectedItem as DoctorType;
                    DoctorAutocompleteTextBox.ItemsSource = selectedType.Doctors;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }


        private void IsPhoneBookingCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            PaymentMethodStackPanel.IsEnabled = !(bool)IsPhoneBookingCheckBox.IsChecked;
            PaymentMethodComboBox.SelectedIndex = 1;
        }


        private void IsPhoneBookingCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            PaymentMethodStackPanel.IsEnabled = !(bool)IsPhoneBookingCheckBox.IsChecked;
            PaymentMethodComboBox.SelectedIndex = 0;
        }

        
        //bacground worker used to show progrees dialog
        private void SaveBackgroundWorker(object sender, DoWorkEventArgs e)
        {
            try
            {
                //dispathcher needs to access ui control without having exceptions
                this.Dispatcher.Invoke((Action)(() =>
                {
                     this.Save();
                 }));
            
                
            }
            catch (Exception)
            {               
                throw;
            }           
        }

        //bacground worker used to show progrees dialog
        private void PrintBackgroundWorker(object sender, DoWorkEventArgs e)
        {
            try
            {
                //dispathcher needs to access ui control without having exceptions
                this.Dispatcher.Invoke((Action)(() =>
                {                
                    Channeling selectedChanneling = ReferenceAutocompleteTextBox.SelectedItem as Channeling;
                    this.Print(selectedChanneling); 
                }));

            }
            catch (Exception)
            {
                throw;
            }
        }

      

        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //show the busy indicator of saving
                 ProgressWindow = new ProgressWindow(this.SaveBackgroundWorker);
                 ProgressWindow.Owner = this;
                 ProgressWindow.ShowDialog();
            }
            catch (Exception ex)
            {               
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);   
            }          
        }


     
        private void ChannelingHourComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (CurrentFormAction == FormAction.New)
                {
                    this.UpdateSummary();
                }
            }
            catch (Exception ex)
            {               
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }


        private void Cancelbutton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (ReferenceAutocompleteTextBox.SelectedItem != null)
                {
                    this.Cancel();
                }
                else
                {
                    MessageBox.Show(Properties.Resources.ChannelingNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }


        private void DoctorAutocompleteTextBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CurrentFormAction == FormAction.New && DoctorAutocompleteTextBox.SelectedItem != null)
            {
                Doctor selectedDoctor=DoctorAutocompleteTextBox.SelectedItem as Doctor;
                DoctorFeeTextBlock.Text = selectedDoctor.DoctorFee.Value.ToString();
                HospitalFeeTextBlock.Text = selectedDoctor.HospitalFee.Value.ToString();
                TotalReceiptAmountTextBlock.Text = this.CalculateTotalReceiptAmount(selectedDoctor, 0).ToString();
                UpdateSummary();
            }
        }


        private void RefreshSummaryButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.UpdateSummary();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }


        private void NewButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.CurrentFormAction = FormAction.New;

                //Context refreshed to get new reference
                HMSContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, HMSContext.SystemNumbers);
                SystemNumber nextSystemNumber= HMSContext.SystemNumbers.Where(s=> s.SystemNumberID==1).First();
                ReferenceAutocompleteTextBox.Text = nextSystemNumber.Prefix + nextSystemNumber.NextNumber;   
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }


        private void ReferenceAutocompleteTextBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (ReferenceAutocompleteTextBox.SelectedItem != null)
                {
                    Channeling selectedChanneling=ReferenceAutocompleteTextBox.SelectedItem as Channeling;
                    this.DisplayDetails(selectedChanneling);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }


        private void PrintButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (ReferenceAutocompleteTextBox.SelectedItem != null)
                {
                    //show the busy indicator of saving
                    ProgressWindow = new ProgressWindow(this.PrintBackgroundWorker);
                    ProgressWindow.Owner = this;
                    ProgressWindow.ShowDialog();
                }
                else
                {
                    MessageBox.Show(Properties.Resources.ChannelingNotSet, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        private void AppointmentDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (CurrentFormAction == FormAction.New)
                {
                    this.UpdateSummary();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

       
       
    }
}
